package com.zkh.myutils.proxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.function.Consumer;

import com.zkh.myutils.proxy.util.ParamReader;

/**
 * 代理方法对象
 * @author zkh
 */
public class ProxyMethod {
	//参数名
	private List<String> argNames;
	//参数
	private Object[] args;
	//代理方法
	private Method method;
	//代理方法名
	private String name;
	//原方法名
	private String superName;
	//代理类名
	private String className;
	//原类名
	private String superClassName;
	
	public ProxyMethod(Method method, String name, String superName,
			String className, String superClassName, Object[] args, List<String> argNames) {
		super();
		this.method = method;
		this.name = name;
		this.superName = superName;
		this.className = className;
		this.superClassName = superClassName;
		this.args = args;
		this.argNames = argNames;
	}
	
	/**
	 * 遍历参数名和参数值
	 * @param consumer
	 */
	public void forEachParam(Consumer<ParamReader> consumer) {
		//获取参数对象
		Parameter[] ps = method.getParameters();
		//遍历参数
		for(int i=0, len=ps.length; i<len; i++) {
			//当前参数
			Parameter p = ps[i];
			//参数对象并保存
			consumer.accept(new ParamReader(argNames.get(i), args[i], p.getType(), p.getParameterizedType(), i));
		}
	}

	/**
	 * 执行代理方法。也可以使用getMethod().invoke(Object obj, Object... args)方法执行
	 * @param obj 实例对象
	 * @param args 参数
	 * @return
	 */
	public Object invoke(Object obj, Object... args) 
			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		return method.invoke(obj, args);
	}

	public void setArgs(Object[] args) {
		this.args = args;
	}

	public Object[] getArgs() {
		return args;
	}

	public Method getMethod() {
		return method;
	}

	public void setMethod(Method method) {
		this.method = method;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSuperName() {
		return superName;
	}

	public void setSuperName(String superName) {
		this.superName = superName;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getSuperClassName() {
		return superClassName;
	}

	public void setSuperClassName(String superClassName) {
		this.superClassName = superClassName;
	}
}
